First things first – we have to setup your computer to work with Julia.
Fortunately, this is easy regardless of the OS you use! Less easy is the mental preparation, specifically your head around the idea of a functional programming language.
Therefore, the first part of this chapter will attempt a brief course in re-educating object-oriented programmers, which you should definitely read if you have been mainly using an object-oriented paradigm. In fact, you should read it anyway.
When writing code, we follow some basic concepts about building up a complex structure from simple building blocks. The highest, most abstract level of these concepts is that of programming paradigms. A paradigm can be understood as a very broad guiding idea of writing code.
A procedural or imperative programming style uses a series of instructions in sequence. This is how most of us have started out programming: one instruction after another.
Eventually, it gets more complicated, and subroutines have to get involved to achieve modularity, but ultimately, the idea of procedural programming is to take one step after another, in sequence.
OOP, the dominant programming trend, is different. OOP has great reliance on the idea of objects, based on prototypes (often called classes), which are created (instantiated, to use OOP lingo) at a given time.
These objects have particular data fields (called attributes or instance variables) and their own bits of code (methods) operating on the instance variables, the object and the world at large. Every object is an instance of a class, that is, it derives its basic form from a pre-defined blueprint. Of course, that's a very simplistic description of an extremely complex idea, but do bear with me for the moment.
FP is is similar to the original procedural idea. The main point of functional programming is, as the name suggests, to execute functions. In this way, it is very close to mathematics - so close, in fact, that it is based to a great extent on the concept of a lambda calculus, devised by Alonso Church, well before there were computers (Also where python's lambda
comes from)!
Instead of classes, some functional languages, such as Julia, have the concept of types. A type is, quite simply, the kind of structure that a particular bit of information is. For instance, we are all familiar with strings and integers as types, but various other types exist, and there is nothing that keeps you from inventing your own (such as a type representing geographic coordinates).
Functional programming is older than OOP – Lisp, the great big ancestor of all things functional (and many things that are not!), was devised in the 1950s by John McCarthy. However, since then, they have mostly been used in academia to teach computing concepts to first-year undergraduates who can't wait to progress on to something they can use in the real world. One of the reasons for this was the need to represent changing data.
Objects have state, that is, at a given time, their instance variables or attributes have a particular value, which can change depending on what happens in the real world: an object that represents a bank account, for instance, might have a balance attribute that may change if the account holder credits money or withdraws from it. Object-oriented languages are more efficient in representing state and making sure that concurrent transactions affect the object in the right order.
Equally, functional languages were seen as less efficient when compared to imperative languages, such as C. This restricted functional languages to a primarily academic role. That is, until it was realised that functional languages can be useful for distributed systems.
This spawned a new interest in the new generation of functional languages, such as Haskell, Clojure and Scala. The latter is used by Twitter extensively to manage long-running distributed processes, such as its message queuing and caching layers, while Clojure is used by a number of financial institutions and Big Data intensive users because of the ability to use Java libraries and access Hadoop/HBase easily.
Functional programming is no longer a purely academic pursuit.
Julia marries the idea of functional programming to field of statistical or scientific programming. For this reason, much of Julia should come naturally to those more inclined to mathematical thought than the more systemic perspective that OOP people generally have.
As an OOP programmer, you might find yourself at a loss at times. This is normal. Experimenting with a new programming paradigm is always an endeavour that requires some mental restructuring. However, it is worthwhile – not only are multi-paradigm coders generally in higher demand, your OOP code might improve by learning functional tricks as most OOP languages do have some minimal facilities for functional programming strategies. After all, we earn our keep by finding the most appropriate solutions – whether that's speed, reliability or taking advantage of distributed system power – for the problems we encounter. It can't ever hurt to have another arrow in our quiver.
You might be used to things being called as methods, whereas in Julia, they will be called as functions: so e.g. Python's array.push(x)
would correspond to Julia's push!(array, x)
.
Data constructs are expressed through types. These can be as complex as classes, or sometimes even more so!
Not strictly an OOP versus functional thing, but Julia is 1-indexed, not 0-indexed. The n_th element of an indexable collection has the index n, not n-1.
If you use Windows, Mac OS X, Ubuntu, Fedora/RHEL/CentOS or a generic Linux distribution that does packages, the download page for the Julia language is the easiest way to obtain an installer or package version of Julia.
For the purposes of this book, we will assume you're using version v0.4. Julia is a young language, and it is developing quite a lot (although the core features have been stable for a pretty long time). There is, currently, no guarantee that the final version – or, indeed, the next version! – will look anything like it currently does.
If you're using a *NIX distribution, you might be able to use your distro's package manager to get Julia. These are a better option for folks who have hardware or dependency issues while compiling Julia from source. Do remember that if you have installed and update your local copy of Julia via the package manager's nightly builds, you need to be aware that they run from a different directory than when you compile Julia from source.
sudo add-apt-repository ppa:staticfloat/juliareleases
sudo add-apt-repository ppa:staticfloat/julia-deps
sudo apt-get update
sudo apt-get install julia
sudo dnf copr enable nalimilan/julia
sudo yum install julia
sudo pacman -S julia
brew install julia
Julia changes rapidly, with often more than a dozen average changes per day (!) to the source code. Therefore, some people tend to simply pull the most recent nightly build from Git and recompile it every few days. This is a great way to stay ahead of the curve, and also to come across more bugs than one would want to when learning a new language. By all means do use nightly builds when you are confident with Julia, but I do not recommend doing so for the time you are trying to navigate your way through it.
If you do want to use nightly builds (a.k.a PPA's), simply pull the master branch from the Julia GitHub repo and compile by typing make into the Terminal. To speed up the process, you might wish to use a number of concurring processes (make -j n
, where n is the number of concurrent processes you are going to use).
There is an implementation of the vastly successful Jupyter notebook environment (which we are currently in!) for Julia.
The IPython system, now known as the Jupyter project, is a great way to interactively use Julia in a notebook environment that users of Mathematica or similar software might be used to. It also allows literate coding, mixing Markdown notes and formatting with executable code.
To install IJulia, you will need an existing IPython installation, either a distribution like Anaconda or by installing Python and the IPython notebook environment by downloading the Python distribution for your operating system.
Once that is in place, you will need to install Julia using the instructions above.
To launch Julia, open a Terminal and type julia
, which will drop you into the REPL that looks something like:
$ julia
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: http://docs.julialang.org
_ _ _| |_ __ _ | Type "?help" for help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 0.4.6 (2016-06-19 17:16 UTC)
_/ |\__'_|_|_|\__'_| | Official http://julialang.org/ release
|__/ | x86_64-apple-darwin13.4.0
julia>
Now, you can install IJulia using the Pkg.add("IJulia")
command. Congratulations, you now have your very own notebook environment for Julia!
You can fire up the Julia REPL and launch a Julia notebook environment by:
using IJulia
notebook()
Alternatively, to launch your environment, open a new terminal tab to use the profile IPython parameter:
$ ipython notebook --profile julia
CoLaboratory is the brainchild of the IPython team. Leveraging the experience and success of IPython, it aims at creating a similar experience, in the cloud, for R and Julia. CoLaboratory is based on Chrome Apps and Google Docs, using the latter as a storage platform. CoLaboratory is a great tool for pair programming and exploring Python, R or Julia together, or for working together on complex projects.
A good introduction to CoLaboratory is this tutorial by Eric Hare and Andee Kaplan. CoLaboratory can be a great alternative to your own local Python installation, especially if scientific programming in the 'notebook' context is your thing (migrants from Mathematica are certain to welcome this feature!).
JuliaBox is a project supported by Julia's core team, Juliabox allows you to code, store and share your work with other people. However, it is still in beta and mainly used for classroom work by MIT, Stanford and CUNY. Logins are time limited and there are performance limitations. JuliaBox uses a virtual docker instance that it uses to control and execute your work in a segregated environment. If you want to play around with Julia without the need to set up anything on your own computer, JuliaBox is a good alternative. Since notebooks created on JuliaBox are effectively IJulia notebooks, the interface will be quite familiar.
As previously noted, this book diverges from Zed Shaw's framework a little. As such, I will not take you through the intricacies of setting up an IDE or a text editor. To cut a rather long story short – use what works for you! Fortunately, most text editors do have some form of support for Julia:
Open up Julia by launching IJulia, opening the Julia app provided with the macOS version or calling Julia from the terminal (usually, julia). You are greeted by the Julia REPL.
$ julia
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: http://docs.julialang.org
_ _ _| |_ __ _ | Type "?help" for help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 0.4.6 (2016-06-19 17:16 UTC)
_/ |\__'_|_|_|\__'_| | Official http://julialang.org/ release
|__/ | x86_64-apple-darwin13.4.0
julia>
Your version may differ, as will the architecture (final line). If you seek help on Julia forums, always be sure to mention what build you have (the final three lines).
Congratulations. (Y)our adventure begins here.